import { getCpasTableCells, getDisclosureApiData } from "../api/DesignTableApi";
function isBracket(c) {
    return c === "(" || c === ")";
}
function isOper(c) {
    return (c === "(" || c === ")" || c === "+" || c === "-" || c === "*" || c === "/");
}
function getPriority(oper) {
    switch (oper) {
        case "+":
        case "-":
            return 0;
        case "*":
        case "/":
            return 1;
        case "(":
        case ")":
            return -1;
        default:
            return -2;
    }
}
export default class CustomFormulaService {
    //表内存级别缓存
    memoryCacheTable = {};
    //公式内存级别缓存
    memoryCacheFormula = {};
    handlerSymbol(c, postfixHelper, postfix) {
        if (postfixHelper.empty()) {
            postfixHelper.push(c);
            return;
        }
        if (isBracket(c)) {
            if (c === "(")
                postfixHelper.push(c);
            else {
                // 弹出所有元素直到遇到左括号
                while (postfixHelper.top() !== "(") {
                    let ch = postfixHelper.top();
                    postfix.push(ch);
                    postfixHelper.pop();
                }
                // 当遇到左括号时，弹出但不加入postfix(后缀表达式中）
                postfixHelper.pop();
            }
        }
        else {
            // 如果不是括号
            // 取出栈顶元素，与当前符号进行优先性比较
            let sym = postfixHelper.top();
            // 比较两符号的优先性
            if (getPriority(c) <= getPriority(sym)) {
                // 如果c的优先性比栈顶符号小或等于，弹出栈顶元素
                postfixHelper.pop();
                // 并将其压入postfix（后缀表达式）中
                postfix.push(sym);
                // 递归调用handler,比较当前符号c与下一个栈顶符号的优先性
                this.handlerSymbol(c, postfixHelper, postfix);
            }
            else {
                // 如果c比栈顶符号优先级大，那将c压入coll2(操作符栈）中
                postfixHelper.push(c);
            }
        }
    }
    /**
     * 检测是否为自定义公式
     */
    static isCustomFormula(value) {
        if (typeof value !== "string") {
            return false;
        }
        if (value.startsWith("=CP_CELL") ||
            value.startsWith("=FS_CELL") ||
            value.startsWith("=IN_CELL")) {
            return true;
        }
    }
    /**
     * 提取公式中的自定义公式
     * @param formula
     */
    static getHyperCustomFormula(formula) {
        const formula_reg = /(CP_CELL?.*?\(.+?\))|(FS_CELL:?.*?\(.+?\))|(IN_CELL:?.*?\(.+?\))/g;
        const result = formula.match(formula_reg);
        //提取参数
        //提取后的公式 const re = result[0]
        // re.substring(re.indexOf("(")+1).split(",")
        //重复公式去重
        return Array.from(new Set(result));
    }
    /**
     * 提取公式的参数
     */
    static getHyperCustomFormulaParams(formula) {
        const formula_params_start = formula.indexOf("(") + 1;
        const formula_params_end = formula.indexOf(")");
        return formula
            .substring(formula_params_start, formula_params_end)
            .split(",");
    }
    /**
     * 将公式中的取数公式进行数字替换
     *
     * @param formula
     */
    async parseFormula(formula) {
        formula = formula.replace("=", "");
        formula = formula.replaceAll('"', "");
        //提取公式列表
        const formula_list = CustomFormulaService.getHyperCustomFormula(formula);
        if (!formula_list) {
            return formula;
        }
        const formulaParse = {};
        for (let i = 0; i < formula_list.length; i++) {
            //单个公式
            let formula = formula_list[i];
            //获取公式名
            const funName = formula.substring(0, formula.indexOf("("));
            //获取参数
            const params = CustomFormulaService.getHyperCustomFormulaParams(formula);
            let value;
            if (funName === "FS_CELL") {
                value = await this.parseFSFormula(params, formula);
            }
            else if (funName === "CP_CELL") {
                value = await this.parseCPFormula(params, formula);
            }
            else if (funName === "IN_CELL") {
            }
            formulaParse[formula] = value;
        }
        for (let f in formulaParse) {
            const value = formulaParse[f];
            formula = formula.replaceAll(f, value);
        }
        return formula;
    }
    /**
     * FS_CELL公式解析
     */
    async parseFSFormula(params, formula) {
        if (params.length < 4) {
            throw new Error("FS公式参数不正确");
        }
        const [tableName, primaryKey, columnName, dataId] = params;
        try {
            if (this.memoryCacheFormula[formula]) {
                return this.memoryCacheFormula[formula];
            }
            let result = this.memoryCacheTable[tableName + "_" + dataId];
            if (!result) {
                const response = await getDisclosureApiData(tableName, dataId);
                if (response.ok) {
                    result = response.data;
                    this.memoryCacheTable[tableName + "_" + dataId] = result;
                }
            }
            //获取不到数据，解析公式为0
            if (!result) {
                return 0;
            }
            for (let i = 0; i < result.length; i++) {
                const row = result[i];
                if (!row["主键"]) {
                    throw new Error("未检测到主键");
                }
                if (row["主键"] === primaryKey) {
                    this.memoryCacheFormula[formula] = row[columnName];
                    return row[columnName];
                }
            }
        }
        catch (e) {
            throw e;
        }
    }
    /**
     * CP_CELL公式解析
     */
    async parseCPFormula(params, formula) {
        if (params.length < 3) {
            throw new Error("CP公式参数不正确");
        }
        let tableName = null, rmap = null, cmap = null, data_id = null;
        if (params.length === 3) {
            [tableName, rmap, cmap] = params;
        }
        if (params.length === 4) {
            [tableName, rmap, cmap, data_id] = params;
        }
        if (!tableName) {
            throw new Error("未检测到表名");
        }
        let type = "fs";
        const parseTName = tableName.split("|");
        if (parseTName.length > 1) {
            type = parseTName[1] === "前" ? "ds" : "zl";
        }
        try {
            if (this.memoryCacheFormula[formula]) {
                return this.memoryCacheFormula[formula];
            }
            let result;
            if (type === "fs") {
                result = this.memoryCacheTable[tableName + "_" + data_id];
            }
            else {
                result = this.memoryCacheTable[tableName];
            }
            if (!result) {
                let response;
                if (type === "fs") {
                    response = await getCpasTableCells(tableName, data_id, type);
                }
                else {
                    response = await getCpasTableCells(parseTName[0], data_id, type);
                }
                if (response.ok) {
                    result = response.data;
                    if (type === "fs") {
                        this.memoryCacheTable[tableName] = result;
                    }
                    else {
                        this.memoryCacheTable[tableName + "_" + data_id] = result;
                    }
                }
                //获取不到数据，解析公式为0
                if (!result) {
                    return 0;
                }
                for (let i = 0; i < result.length; i++) {
                    const row = result[i];
                    if (row["rmap"] === rmap && row["cmap"] === cmap) {
                        this.memoryCacheFormula[formula] = row["dValue"];
                        return row["dValue"];
                    }
                }
            }
        }
        catch (e) {
            throw e;
        }
    }
}
